﻿
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;

namespace WSU.ChekaParallel.TestTask
{
    static class TestThreadLocalStorage
    {
        /// <summary>
        /// chekanote: TLS is Thread-Local-Storage, other than Task-Local-Storage
        /// a single thread can run multiple task
        /// so a TLS variable can be shared among different tasks
        /// and accumulate previous state
        /// </summary>
        private static void TestNotTaskLocalStorage()
        {
            ThreadLocal<int> tls = new ThreadLocal<int>();

            const int NumTasks = 10;
            const int LoopPerTask = 1000;

            Task<int>[] tasks = new Task<int>[NumTasks];
            for (int index = 0; index < NumTasks; ++index)
            {
                int taskid = index + 1;
                tasks[index] = Task.Factory.StartNew<int>(() =>
                    {
                        Console.WriteLine("[Begin] Task<{0}>'s intial value={1}", taskid, tls.Value);

                        for (int loop = 0; loop < LoopPerTask; ++loop)
                            tls.Value += 1;

                        Console.WriteLine("-----------[End] Task<{0}>'s end value={1}", taskid, tls.Value);
                        return tls.Value;
                    });
            }

            int actualResult = tasks.Aggregate(0, (total, t) => total + t.Result);
            // chekanote: just because TLS is thread-local-storage, so a single TLS may be shared between 
            // multiple tasks. when a task take over a TLS, that TLS may have the legacy of the previous task
            // so if below codes uses "assert" to check equality between actual value and expected value, it may fail
            Console.WriteLine("Expected={0} VS. Actual={1}", (LoopPerTask * NumTasks), actualResult);
        }

        public static void TestMain()
        {
            TestNotTaskLocalStorage();
        }
    }
}